package org.csu.onlineedubackend.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.csu.onlineedubackend.dto.*;
import org.csu.onlineedubackend.entity.Chapter;
import lombok.extern.slf4j.Slf4j;
import org.csu.onlineedubackend.dto.CourseCommentDTO;
import org.csu.onlineedubackend.dto.CourseDetailDTO;
import org.csu.onlineedubackend.dto.CreateCourseDTO;
import org.csu.onlineedubackend.entity.Course;
import org.csu.onlineedubackend.entity.CourseBookmark;
import org.csu.onlineedubackend.entity.CourseComment;
import org.csu.onlineedubackend.entity.User;
import org.csu.onlineedubackend.entity.Chapter;
import org.csu.onlineedubackend.entity.Lesson;
import org.csu.onlineedubackend.mapper.*;

import org.csu.onlineedubackend.service.*;
import org.csu.onlineedubackend.util.HashIdUtil;
import org.csu.onlineedubackend.service.CourseService;
import org.csu.onlineedubackend.service.StudentCourseService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.*;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;

@Service
@Slf4j
public class CourseServiceImpl extends ServiceImpl<CourseMapper, Course> implements CourseService {

    
    // private final ChapterMapper chapterMapper;
    // private final LessonMapper lessonMapper;
    // private final CourseCommentMapper courseCommentMapper;
    @Autowired
    private CourseMapper courseMapper;
    
    @Autowired
    private UserMapper userMapper;

    @Autowired
    private ChapterMapper chapterMapper;
    
    @Autowired
    private LessonMapper lessonMapper;
    
    @Autowired
    private StudentCourseService studentCourseService;

    @Autowired
    private ChapterService chapterService;

    @Autowired
    private LessonService lessonService;

    @Autowired
    private CourseSubscribeMapper courseSubscribeMapper;

    @Autowired
    @Qualifier("redisTemplate11")
    private RedisTemplate<String, Object> redisTemplate;

    @Autowired
    private CourseCommentMapper courseCommentMapper;


    @Autowired
    private CourseBookmarkMapper courseBookmarkMapper;

    @Override
    public IPage<Course> getCourses(Page<Course> page, String level, String subject, String sort) {
        QueryWrapper<Course> wrapper = new QueryWrapper<>();
        
        // 根据级别筛选
        if (level != null && !level.isEmpty()) {
            wrapper.eq("level", level);
        }
        
        // 根据学科/类别筛选
        if (subject != null && !subject.isEmpty()) {
            wrapper.eq("category", subject);
        }

        // 排序
        if (sort != null) {
            switch (sort) {
                case "price_asc":
                    wrapper.orderByAsc("price");
                    break;
                case "price_desc":
                    wrapper.orderByDesc("price");
                    break;
                case "newest":
                    wrapper.orderByDesc("created_at");
                    break;
                case "popular":
                    wrapper.orderByDesc("subscriber_count");
                    break;
                default:
                    wrapper.orderByDesc("created_at");
            }
        } else {
            // 默认按创建时间倒序
            wrapper.orderByDesc("created_at");
        }

        return courseMapper.selectPage(page, wrapper);
    }

    @Override
    public CourseDetailDTO getCourseDetail(Integer courseId, Integer studentId) {
        log.info("获取课程详情 - 课程ID: {}, 学生ID: {}", courseId, studentId);
        
        try {
            // 参数校验
            if (courseId == null) {
                log.error("获取课程详情失败 - 课程ID为空");
                return null;
            }
            
            // 获取课程基本信息
            Course course = getById(courseId);
            if (course == null) {
                log.warn("获取课程详情失败 - 课程不存在, 课程ID: {}", courseId);
                return null;
            }
            
            log.info("获取课程基本信息成功 - 课程ID: {}, 标题: {}", courseId, course.getTitle());
    
            // 构建返回对象
            CourseDetailDTO dto = new CourseDetailDTO();
            try {
                // 设置基本属性
                dto.setId(course.getId().longValue());
                dto.setTitle(course.getTitle());
                dto.setCategory(course.getCategory());
                dto.setLevel(course.getLevel());
                dto.setPrice(course.getPrice());
                dto.setCoverImage(course.getCoverUrl());
                dto.setDescription(course.getIntroMd());
                dto.setTotalStudents(courseSubscribeMapper.countByCourseId(course.getId()));

                
                log.info("设置课程基本属性成功 - 课程ID: {}", courseId);
            } catch (Exception e) {
                log.error("设置课程基本属性失败 - 课程ID: {}, 错误: {}", courseId, e.getMessage());
                System.out.println("设置课程基本属性异常详细信息：");
                e.printStackTrace();
                // 继续执行，不影响其他信息的获取
            }
    
            try {
                // 获取教师信息
                if (course.getTeacherId() != null) {
                    User teacher = userMapper.selectById(course.getTeacherId());
                    if (teacher != null) {
                        dto.setTeacherId(teacher.getId());
                        dto.setTeacherName(teacher.getUsername());
                        dto.setTeacherAvatar(teacher.getAvatar());
                        dto.setTeacherTitle("讲师");
                        dto.setTeacherDescription("专业教师");
                        log.info("获取教师信息成功 - 课程ID: {}, 教师ID: {}, 教师名: {}", courseId, teacher.getId(), teacher.getUsername());
                    } else {
                        log.warn("获取教师信息失败 - 教师不存在, 课程ID: {}, 教师ID: {}", courseId, course.getTeacherId());
                    }
                } else {
                    log.info("课程无教师信息 - 课程ID: {}", courseId);
                }
            } catch (Exception e) {
                log.error("获取教师信息异常 - 课程ID: {}, 错误: {}", courseId, e.getMessage());
                System.out.println("获取教师信息异常详细信息：");
                e.printStackTrace();
                // 继续执行，不影响其他信息的获取
            }
    
            try {
                // 获取所有章节和课时信息
                List<CourseDetailDTO.ChapterDTO> chapterDTOs = new ArrayList<>();
                
                // 使用ChapterMapper查询所有章节
                QueryWrapper<Chapter> chapterQuery = new QueryWrapper<>();
                chapterQuery.eq("course_id", courseId);
                chapterQuery.orderByAsc("sort_order");
                List<Chapter> chapters = chapterMapper.selectList(chapterQuery);
                log.info("查询章节信息成功 - 课程ID: {}, 章节数: {}", courseId, chapters.size());
                
                // 遍历章节，获取每个章节的课时
                for (Chapter chapter : chapters) {
                    try {
                        CourseDetailDTO.ChapterDTO chapterDTO = new CourseDetailDTO.ChapterDTO();
                        chapterDTO.setId(chapter.getId().longValue());
                        chapterDTO.setTitle(chapter.getTitle());
                        chapterDTO.setSequence(chapter.getSortOrder());
                        
                        // 查询该章节下的所有课时
                        QueryWrapper<Lesson> lessonQuery = new QueryWrapper<>();
                        lessonQuery.eq("chapter_id", chapter.getId());
                        lessonQuery.orderByAsc("sort_order");
                        List<Lesson> lessons = lessonMapper.selectList(lessonQuery);
                        log.info("查询章节课时成功 - 章节ID: {}, 课时数: {}", chapter.getId(), lessons.size());
                        
                        // 如果有课时，使用第一个课时的信息
                        if (!lessons.isEmpty()) {
                            Lesson firstLesson = lessons.get(0);
                            chapterDTO.setVideoUrl(firstLesson.getVideoUrl());
                            chapterDTO.setDuration(firstLesson.getDuration());
                            // 设置是否可试看 - 第一章的第一个课时可以试看，其他需要根据isPreview字段判断
                            chapterDTO.setIsPreviewable(firstLesson.getIsPreview() || chapter.getSortOrder() == 1);
                        } else {
                            // 没有课时的情况
                            chapterDTO.setVideoUrl("");
                            chapterDTO.setDuration(0);
                            chapterDTO.setIsPreviewable(chapter.getSortOrder() == 1); // 第一章默认可试看
                            log.info("章节无课时 - 章节ID: {}", chapter.getId());
                        }
                        
                        chapterDTOs.add(chapterDTO);
                    } catch (Exception e) {
                        log.error("处理章节信息异常 - 章节ID: {}, 错误: {}", chapter.getId(), e.getMessage());
                        System.out.println("处理章节信息异常详细信息：");
                        e.printStackTrace();
                        // 继续处理下一个章节
                    }
                }
                
                // 如果没有章节数据，添加一个默认章节
                if (chapterDTOs.isEmpty()) {
                    CourseDetailDTO.ChapterDTO defaultChapter = new CourseDetailDTO.ChapterDTO();
                    defaultChapter.setId(1L);
                    defaultChapter.setTitle("第一章 - 课程介绍");
                    defaultChapter.setSequence(1);
                    defaultChapter.setVideoUrl("/videos/intro.mp4");
                    defaultChapter.setDuration(300); // 5分钟
                    defaultChapter.setIsPreviewable(true);
                    chapterDTOs.add(defaultChapter);
                    log.info("课程无章节数据，添加默认章节 - 课程ID: {}", courseId);
                }
                
                dto.setChapters(chapterDTOs);
                log.info("设置课程章节信息成功 - 课程ID: {}, 章节数: {}", courseId, chapterDTOs.size());
            } catch (Exception e) {
                log.error("获取章节信息异常 - 课程ID: {}, 错误: {}", courseId, e.getMessage());
                System.out.println("获取章节信息异常详细信息：");
                e.printStackTrace();
                // 设置空章节列表，避免前端出错
                dto.setChapters(new ArrayList<>());
            }
            
            try {
                // 设置订阅和收藏状态
                boolean isPurchased = false;
                if (studentId != null) {
                    try {
                        isPurchased = studentCourseService.isSubscribed(studentId, courseId);
                        log.info("查询学生订阅状态成功 - 课程ID: {}, 学生ID: {}, 是否订阅: {}", courseId, studentId, isPurchased);
                    } catch (Exception e) {
                        log.error("调用studentCourseService.isSubscribed失败 - 课程ID: {}, 学生ID: {}, 错误: {}", 
                                courseId, studentId, e.getMessage(), e);
                        
                        // 备用方案：直接查询数据库
                        try {
                            // 直接查询student_course表
                            isPurchased = courseMapper.checkStudentSubscription(studentId, courseId) > 0;
                            log.info("备用方案查询订阅状态成功 - 课程ID: {}, 学生ID: {}, 是否订阅: {}", 
                                    courseId, studentId, isPurchased);
                        } catch (Exception ex) {
                            log.error("备用方案查询订阅状态也失败 - 课程ID: {}, 学生ID: {}, 错误: {}", 
                                    courseId, studentId, ex.getMessage(), ex);
                            // 默认为未订阅
                            isPurchased = false;
                        }
                    }
                    
                    dto.setIsPurchased(isPurchased);
                    
                    // 检查是否已收藏
                    try {
                        boolean isBookmarked = courseMapper.checkStudentBookmark(studentId, courseId) > 0;
                        dto.setIsBookmarked(isBookmarked);
                        log.info("查询学生收藏状态成功 - 课程ID: {}, 学生ID: {}, 是否收藏: {}", courseId, studentId, isBookmarked);
                    } catch (Exception e) {
                        log.error("查询收藏状态失败 - 课程ID: {}, 学生ID: {}, 错误: {}", 
                                courseId, studentId, e.getMessage(), e);
                        // 备用方案：使用CourseBookmarkMapper
                        try {
                            QueryWrapper<CourseBookmark> bookmarkWrapper = new QueryWrapper<>();
                            bookmarkWrapper.eq("student_id", studentId).eq("course_id", courseId);
                            boolean isBookmarked = courseBookmarkMapper.selectCount(bookmarkWrapper) > 0;
                            dto.setIsBookmarked(isBookmarked);
                            log.info("备用方案查询收藏状态成功 - 课程ID: {}, 学生ID: {}, 是否收藏: {}", 
                                    courseId, studentId, isBookmarked);
                        } catch (Exception ex) {
                            log.error("备用方案查询收藏状态也失败 - 课程ID: {}, 学生ID: {}, 错误: {}", 
                                    courseId, studentId, ex.getMessage(), ex);
                            // 默认为未收藏
                            dto.setIsBookmarked(false);
                        }
                    }
                } else {
                    dto.setIsPurchased(false);
                    dto.setIsBookmarked(false);
                    log.info("未提供学生ID，设置默认订阅和收藏状态为false - 课程ID: {}", courseId);
                }
            } catch (Exception e) {
                log.error("获取订阅和收藏状态异常 - 课程ID: {}, 学生ID: {}, 错误: {}", courseId, studentId, e.getMessage(), e);
                // 设置默认值，避免前端出错
                dto.setIsPurchased(false);
                dto.setIsBookmarked(false);
            }
            
            try {
                // 查询评论总数和平均评分
                QueryWrapper<CourseComment> commentQuery = new QueryWrapper<>();
                commentQuery.eq("course_id", courseId);
                Long commentCountLong = courseCommentMapper.selectCount(commentQuery);
                int commentCount = commentCountLong != null ? commentCountLong.intValue() : 0;
                dto.setTotalComments(commentCount);
                log.info("查询评论总数成功 - 课程ID: {}, 评论数: {}", courseId, commentCount);
                
                // 计算平均评分
                if (commentCount > 0) {
                    // 使用SQL查询平均评分
                    Double avgRating = courseCommentMapper.selectAvgRatingByCourseId(courseId);
                    if (avgRating != null) {
                        dto.setAverageRating(avgRating);
                        log.info("计算平均评分成功 - 课程ID: {}, 平均评分: {}", courseId, avgRating);
                    } else {
                        dto.setAverageRating(0.0);
                        log.info("计算平均评分为空，设置为0 - 课程ID: {}", courseId);
                    }
                } else {
                    dto.setAverageRating(0.0);
                    log.info("无评论，平均评分设置为0 - 课程ID: {}", courseId);
                }
            } catch (Exception e) {
                log.error("获取评论信息异常 - 课程ID: {}, 错误: {}", courseId, e.getMessage());
                System.out.println("获取评论信息异常详细信息：");
                e.printStackTrace();
                // 设置默认值，避免前端出错
                dto.setTotalComments(0);
                dto.setAverageRating(0.0);
            }
            
            log.info("获取课程详情成功 - 课程ID: {}", courseId);
            return dto;
        } catch (Exception e) {
            log.error("获取课程详情异常 - 课程ID: {}, 错误: {}", courseId, e.getMessage());
            System.out.println("获取课程详情异常详细信息：");
            e.printStackTrace();
            return null;
        }
    }
    // @Override
    // public List<Course> getCoursesByTeacherId(Integer teacherId) {
    //     QueryWrapper<Course> wrapper = new QueryWrapper<>();
    //     wrapper.eq("teacher_id", teacherId);
    //     return courseMapper.selectList(wrapper);
    // }

    @Override
    public CourseDetailDTO getCourseBasicDetail(Integer courseId, Integer studentId) {
        // 简化版的课程详情，不包含章节信息
        CourseDetailDTO dto = getCourseDetail(courseId, studentId);
        if (dto != null) {
            dto.setChapters(new ArrayList<>()); // 清空章节信息
        }
        return dto;
    }
    @Override
    public CourseDTO getCourseInfo(Integer courseId) {
        // 获取课程基本信息
        Course course = courseMapper.selectById(courseId);
        if (course == null) {
            return null;
        }

        // 构建CourseDTO
        CourseDTO courseDTO = new CourseDTO();
        courseDTO.setId(course.getId());  // 课程id
        courseDTO.setCourseId(org.csu.onlineedubackend.util.HashIdUtil.generateHashId(course.getId())); // 课程编号（8位哈希）
        courseDTO.setTeacherId(course.getTeacherId()); // 这里的教师id是真正的id
        courseDTO.setTitle(course.getTitle());
        courseDTO.setCategory(course.getCategory());
        courseDTO.setLevel(course.getLevel());
        courseDTO.setCoverUrl(course.getCoverUrl());
        courseDTO.setIntroMd(course.getIntroMd());
        courseDTO.setPrice(course.getPrice());
        courseDTO.setPreviewPercent(course.getPreviewPercent());
        courseDTO.setStatus(course.getStatus());
        courseDTO.setCreatedAt(course.getCreatedAt());
        courseDTO.setUpdatedAt(course.getUpdatedAt());
        courseDTO.setSubscriberCount(courseSubscribeMapper.countByCourseId(course.getId()));

        // 获取教师信息
        if (course.getTeacherId() != null) {
            User teacher = userMapper.selectById(course.getTeacherId());
            if (teacher != null) {
                TeacherDTO teacherDTO = new TeacherDTO();
                teacherDTO.setId(teacher.getId());  // 教师ai
                teacherDTO.setTeacherId(HashIdUtil.generateHashId(teacher.getId()));
                teacherDTO.setName(teacher.getName());
                teacherDTO.setPhone(teacher.getPhone());
                teacherDTO.setAvatarUrl(teacher.getAvatar());
                courseDTO.setTeacher(teacherDTO);
            }
        }

        // 获取章节信息
        QueryWrapper<Chapter> chapterWrapper = new QueryWrapper<>();
        chapterWrapper.eq("course_id", courseId);
        chapterWrapper.orderByAsc("sort_order");
        List<Chapter> chapters = chapterMapper.selectList(chapterWrapper);

        List<ChapterDTO> chapterDTOs = new ArrayList<>();
        int totalDuration = 0;
        int lessonNum = 0;

        for (Chapter chapter : chapters) {
            ChapterDTO chapterDTO = new ChapterDTO();
            chapterDTO.setId(chapter.getId().longValue());
            chapterDTO.setTitle(chapter.getTitle());
            chapterDTO.setSortOrder(chapter.getSortOrder());
            chapterDTO.setCourseId(chapter.getCourseId().longValue());

            // 获取该章节下的所有课程
            QueryWrapper<Lesson> lessonWrapper = new QueryWrapper<>();
            lessonWrapper.eq("chapter_id", chapter.getId());
            lessonWrapper.orderByAsc("sort_order");
            List<Lesson> lessons = lessonMapper.selectList(lessonWrapper);
            chapterDTO.setLessons(lessons);

            // 累计总节数
            lessonNum += lessons.size();

            // 计算章节总时长
            int chapterDuration = 0;
            for (Lesson lesson : lessons) {
                if (lesson.getDuration() != null) {
                    chapterDuration += lesson.getDuration();
                }
            }
            chapterDTO.setDuration(chapterDuration);
            totalDuration += chapterDuration;

            chapterDTOs.add(chapterDTO);
        }

        courseDTO.setChapters(chapterDTOs);
        courseDTO.setTotalDuration(totalDuration);
        courseDTO.setLessonNum(lessonNum);

        return courseDTO;
    }

    @Override
    public IPage<CourseCommentDTO> getCourseComments(Integer courseId, Page<CourseCommentDTO> page) {
        log.info("获取课程评论 - 课程ID: {}, 页码: {}, 每页大小: {}", courseId, page.getCurrent(), page.getSize());
        
        try {
            // 参数校验
            if (courseId == null) {
                log.error("获取课程评论失败 - 课程ID为空");
                return new Page<>(page.getCurrent(), page.getSize());
            }
            
            // 检查课程是否存在
            Course course = getById(courseId);
            if (course == null) {
                log.warn("获取课程评论失败 - 课程不存在, 课程ID: {}", courseId);
                return new Page<>(page.getCurrent(), page.getSize());
            }
            
            // 查询课程评论
            Page<CourseComment> commentPage = new Page<>(page.getCurrent(), page.getSize());
            IPage<CourseComment> commentResult;
            try {
                commentResult = courseCommentMapper.selectCommentsPageByCourseId(commentPage, courseId);
                log.info("查询课程评论成功 - 课程ID: {}, 评论总数: {}", courseId, commentResult.getTotal());
                
                // 打印每条评论的详细信息，帮助调试
                for (CourseComment comment : commentResult.getRecords()) {
                    log.info("评论原始数据 - ID: {}, 课程ID: {}, 用户ID: {}, 内容: {}, 评分: {}, 用户名: {}, 头像: {}", 
                        comment.getId(), comment.getCourseId(), comment.getStudentId(), 
                        comment.getContent(), comment.getStars(), comment.getUsername(), comment.getUserAvatar());
                }
            } catch (Exception e) {
                log.error("查询课程评论异常 - 课程ID: {}, 错误: {}", courseId, e.getMessage());
                System.out.println("查询课程评论异常详细信息：");
                e.printStackTrace();
                return new Page<>(page.getCurrent(), page.getSize());
            }

        // 转换为DTO
        List<CourseCommentDTO> commentDTOs = new ArrayList<>();
            for (CourseComment comment : commentResult.getRecords()) {
                try {
            CourseCommentDTO dto = new CourseCommentDTO();
                    dto.setId(comment.getId());
                    dto.setCourseId(comment.getCourseId());
                    dto.setStudentId(comment.getStudentId());
                    dto.setContent(comment.getContent());
                    dto.setStars(comment.getStars());
                    dto.setLikeCount(comment.getLikeCount());
                    dto.setCreatedAt(comment.getCreatedAt());
                    dto.setStatus(comment.getStatus());
    
                    // 设置用户名和头像
                    dto.setUsername(comment.getUsername() != null ? comment.getUsername() : "未知用户");
                    dto.setUserAvatar(comment.getUserAvatar());
                    
                    // 打印日志，帮助调试
                    log.info("评论数据转换 - 评论ID: {}, 用户ID: {}, 用户名: {}, 头像: {}", 
                        comment.getId(), comment.getStudentId(), dto.getUsername(), dto.getUserAvatar());
                    
                    commentDTOs.add(dto);
                } catch (Exception e) {
                    log.error("处理单条评论异常 - 评论ID: {}, 错误: {}", comment.getId(), e.getMessage());
                    System.out.println("处理单条评论异常详细信息：");
                    e.printStackTrace();
                    // 继续处理下一条评论
                }
            }
            
            // 创建新的分页结果
            Page<CourseCommentDTO> resultPage = new Page<>(
                commentResult.getCurrent(),
                commentResult.getSize(),
                commentResult.getTotal()
            );
            resultPage.setRecords(commentDTOs);
            
            log.info("获取课程评论成功 - 课程ID: {}, 返回评论数: {}", courseId, commentDTOs.size());
            return resultPage;
        } catch (Exception e) {
            log.error("获取课程评论异常 - 课程ID: {}, 错误: {}", courseId, e.getMessage());
            System.out.println("获取课程评论异常详细信息：");
            e.printStackTrace();
            // 返回空页，避免前端出错
            return new Page<>(page.getCurrent(), page.getSize());
        }
    }

    @Override
    public Course getCourseDetailTeacher(Integer courseId) {
        return courseMapper.selectById(courseId);
    }

    @Override
    public boolean addCourseComment(Integer courseId, Integer studentId, String content, Integer rating, String username, String userAvatar) {
        log.info("添加课程评论 - 课程ID: {}, 学生ID: {}, 评分: {}, 用户名: {}", courseId, studentId, rating, username);
        
        try {
            // 参数校验
            if (courseId == null || studentId == null) {
                log.error("添加课程评论失败 - 参数为空, 课程ID: {}, 学生ID: {}", courseId, studentId);
                return false;
            }
            
            if (content == null || content.trim().isEmpty()) {
                log.error("添加课程评论失败 - 评论内容为空");
                return false;
            }
            
            if (rating == null || rating < 1 || rating > 5) {
                log.error("添加课程评论失败 - 评分无效: {}", rating);
                return false;
            }
            
            // 检查课程是否存在
            Course course = getById(courseId);
            if (course == null) {
                log.warn("添加课程评论失败 - 课程不存在, 课程ID: {}", courseId);
                return false;
            }
            
            // 检查学生是否已订阅课程
            try {
                boolean isSubscribed = studentCourseService.isSubscribed(studentId, courseId);
                if (!isSubscribed) {
                    log.warn("添加课程评论失败 - 学生未订阅课程, 课程ID: {}, 学生ID: {}", courseId, studentId);
                    return false; // 未订阅，不允许评价
                }
                log.info("验证学生订阅状态成功 - 课程ID: {}, 学生ID: {}, 已订阅", courseId, studentId);
            } catch (Exception e) {
                log.error("验证学生订阅状态异常 - 课程ID: {}, 学生ID: {}, 错误: {}", courseId, studentId, e.getMessage());
                System.out.println("验证学生订阅状态异常详细信息：");
                e.printStackTrace();
                return false;
            }

            try {
                CourseComment comment = new CourseComment();
                comment.setCourseId(courseId);
                comment.setStudentId(studentId);
                comment.setContent(content);
                comment.setStars(rating);
                comment.setCreatedAt(LocalDateTime.now());
                comment.setStatus(1);
                comment.setLikeCount(0);
                
                // 添加用户名和头像信息
                if (username == null || username.trim().isEmpty()) {
                    // 如果前端没有提供用户名，尝试从数据库获取
                    User user = userMapper.selectById(studentId);
                    if (user != null) {
                        comment.setUsername(user.getUsername());
                        if (userAvatar == null || userAvatar.trim().isEmpty()) {
                            comment.setUserAvatar(user.getAvatar());
                        } else {
                            comment.setUserAvatar(userAvatar);
                        }
                    }
                } else {
                    comment.setUsername(username);
                    comment.setUserAvatar(userAvatar);
                }
                
                int result = courseCommentMapper.insert(comment);
                if (result > 0) {
                    log.info("添加课程评论成功 - 课程ID: {}, 学生ID: {}, 评论ID: {}", courseId, studentId, comment.getId());
                    return true;
                } else {
                    log.warn("添加课程评论失败 - 插入数据库失败, 课程ID: {}, 学生ID: {}", courseId, studentId);
                    return false;
                }
            } catch (Exception e) {
                log.error("添加课程评论异常 - 插入数据库失败, 课程ID: {}, 学生ID: {}, 错误: {}", courseId, studentId, e.getMessage());
                System.out.println("添加课程评论异常详细信息：");
                e.printStackTrace();
                return false;
            }
        } catch (Exception e) {
            log.error("添加课程评论异常 - 课程ID: {}, 学生ID: {}, 错误: {}", courseId, studentId, e.getMessage());
            System.out.println("添加课程评论异常详细信息：");
            e.printStackTrace();
            return false;
        }
    }

    public List<Course> getCoursesByTeacherId(Integer teacherId) {
        return courseMapper.selectList(new QueryWrapper<Course>()
                .eq("teacher_id", teacherId)
                .eq("status", 1) );
    }

    @Override
    public void updateCourse(Course course) {
        // 1. 更新课程本身
        course.setUpdatedAt(LocalDateTime.now());
        this.updateById(course);

        // 2. 更新章节和课时
        if (course.getChapters() != null) {
            for (ChapterWithLessonsDTO chapterDTO : course.getChapters()) {
                Chapter chapter = chapterDTO.getChapter();
                if (chapter.getId() == null) {
                    throw new RuntimeException("章节更新失败：chapter.id 不能为空");
                }
                chapterService.updateById(chapter);

                for (Lesson lesson : chapterDTO.getLessons()) {
                    if (lesson.getId() == null) {
                        throw new RuntimeException("课时更新失败：lesson.id 不能为空");
                    }
                    lessonService.updateById(lesson);
                }
            }
        }
    }
    @Override
    public void deleteCourseById(Integer courseId) {
        this.removeById(courseId);
    }

    @Override
    public void addCourse(Course course) {
        this.save(course);
//        Integer courseId = course.getId();
    }

    @Transactional
    @Override
    public Integer createFullCourse(CreateCourseDTO dto) {
        Course course = dto.getCourse();
        if (course == null) throw new IllegalArgumentException("课程信息不能为空");

        // 先插入课程，生成 course.id
        courseMapper.insert(course);

        for (ChapterWithLessonsDTO cl : dto.getChapters()) {
            Chapter chapter = cl.getChapter();
            chapter.setCourseId(course.getId());
            chapterMapper.insert(chapter);


                for (Lesson lesson : cl.getLessons()) {
                    lesson.setChapterId(chapter.getId());
                    lessonMapper.insert(lesson);
                }
            }

//            return courseId;
        return course.getId();
    }

    @Override
    public List<CourseCommentDTO> getCommentsByCourseId(Integer courseId) {
        return courseCommentMapper.selectCommentsByCourseId(courseId);
    }

    @Override
    public boolean blockComment(Integer commentId) {
        return courseCommentMapper.blockCommentById(commentId) > 0;
    }

    @Override
    public int countByTeacherId(Integer teacherId) {
        return courseMapper.countByTeacherId(teacherId);
    }



    @Override
    public Double getAverageRatingByTeacherId(Integer teacherId) {
        return courseCommentMapper.getAverageRatingByTeacherId(teacherId);
    }

    @Override
    public int countCommentsByTeacherId(Integer teacherId) {
        return courseCommentMapper.countCommentsByTeacherId(teacherId);
    }

    @Override
    public int countStudentsByTeacherId(Integer teacherId) {
        return courseMapper.countStudentsByTeacherId(teacherId);
    }

    @Override
    public List<Course> getRecentlyUpdatedCoursesByTeacherId(Integer teacherId) {
        return courseMapper.selectRecentlyUpdatedCoursesByTeacherId(teacherId);
    }

    @Override
    public Map<String, List<Course>> getDraftBoxCourses(Integer teacherId) {
        List<Course> courses = courseMapper.selectDraftBoxCoursesByTeacherId(teacherId);
        Map<String, List<Course>> grouped = new HashMap<>();

        grouped.put("草稿", new ArrayList<>());
        grouped.put("下架", new ArrayList<>());
        grouped.put("审核中", new ArrayList<>());
        grouped.put("拒绝", new ArrayList<>());

        for (Course course : courses) {
            switch (course.getStatus()) {
                case 0 -> grouped.get("草稿").add(course);
                case 2 -> grouped.get("下架").add(course);
                case 3 -> grouped.get("审核中").add(course);
                case 4 -> grouped.get("拒绝").add(course);
            }
        }
        return grouped;
    }

//    @Override
//    public List<CourseCommentDTO> getCommentsByTeacherId(Integer teacherId) {
//        return courseCommentMapper.selectCommentsByTeacherId(teacherId);
//    }

    @Override
    public Map<String, Object> getCourseCountByStatus() {
        Map<String, Object> result = new HashMap<>();

        // 1. 统计课程状态
        List<Map<String, Object>> rawCounts = courseMapper.getCourseCountGroupByStatus();

        long published = 0, unpublished = 0, pending = 0, rejected = 0;

        for (Map<String, Object> row : rawCounts) {
            int status = ((Number) row.get("status")).intValue();
            long count = ((Number) row.get("count")).longValue();

            switch (status) {
                case 1 -> published = count;
                case 2 -> unpublished = count;
                case 3 -> pending = count;
                case 4 -> rejected = count;
            }
        }

        long total = published + unpublished + pending + rejected;
        result.put("published", published);
        result.put("unpublished", unpublished);
        result.put("pending", pending);
        result.put("rejected", rejected);
        result.put("total", total);

        // 2. 获取课程增长情况（按创建时间）
        LocalDateTime now = LocalDateTime.now();

        // 上月时间范围
        LocalDateTime lastMonth = now.minusMonths(1);
        LocalDateTime lastMonthStart = lastMonth.withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0);
        LocalDateTime lastMonthEnd = lastMonth.withDayOfMonth(lastMonth.toLocalDate().lengthOfMonth()).withHour(23).withMinute(59).withSecond(59);

        // 上上月时间范围
        LocalDateTime twoMonthsAgo = now.minusMonths(2);
        LocalDateTime twoMonthsAgoStart = twoMonthsAgo.withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0);
        LocalDateTime twoMonthsAgoEnd = twoMonthsAgo.withDayOfMonth(twoMonthsAgo.toLocalDate().lengthOfMonth()).withHour(23).withMinute(59).withSecond(59);

        // 查询
        LambdaQueryWrapper<Course> lastMonthQuery = new LambdaQueryWrapper<>();
        lastMonthQuery.between(Course::getCreatedAt, lastMonthStart, lastMonthEnd);
        long lastMonthCourses = courseMapper.selectCount(lastMonthQuery);

        LambdaQueryWrapper<Course> twoMonthsAgoQuery = new LambdaQueryWrapper<>();
        twoMonthsAgoQuery.between(Course::getCreatedAt, twoMonthsAgoStart, twoMonthsAgoEnd);
        long twoMonthsAgoCourses = courseMapper.selectCount(twoMonthsAgoQuery);

        // 计算增长率
        double growthRate = 0.0;
        if (twoMonthsAgoCourses > 0) {
            growthRate = ((double) (lastMonthCourses - twoMonthsAgoCourses) / twoMonthsAgoCourses) * 100;
        }

        String formattedGrowthRate = String.format("%.2f", growthRate);

        result.put("lastMonthCourses", lastMonthCourses);
        result.put("twoMonthsAgoCourses", twoMonthsAgoCourses);
        result.put("growthRate", formattedGrowthRate);
        result.put("growthDirection", growthRate >= 0 ? "up" : "down");
        return result;
    }

    @Override
    public PageResponseDTO<CourseListDTO> getCoursePage(int page, int size) {
        Page<Course> pageParam = new Page<>(page, size);
        QueryWrapper<Course> queryWrapper = new QueryWrapper<>();
        // course.vue只显示状态为1,2的课程（已上架和已下架）
        queryWrapper.in("status", 1, 2);
        queryWrapper.orderByDesc("created_at");
        
        IPage<Course> coursePage = this.page(pageParam, queryWrapper);
        List<CourseListDTO> dtoList = coursePage.getRecords().stream().map(course -> {
            CourseListDTO dto = new CourseListDTO();
            dto.setTitle(course.getTitle());
            // 教师姓名
            User teacher = userMapper.selectById(course.getTeacherId());
            dto.setTeacherName(teacher != null ? teacher.getName() : "");
            dto.setLevel(course.getLevel());
            dto.setCoverUrl(course.getCoverUrl());
            dto.setCourseId(org.csu.onlineedubackend.util.HashIdUtil.generateHashId(course.getId()));
            dto.setPrice(course.getPrice());
            dto.setStatus(course.getStatus());
            dto.setCreatedAt(course.getCreatedAt());
            dto.setSubscriberCount(courseSubscribeMapper.countByCourseId(course.getId()));
            dto.setId(course.getId());

            //  获取课程平均评分
            Double avgStar = courseCommentMapper.selectAvgRatingByCourseId(course.getId());
            dto.setAvgStart(avgStar != null ? avgStar : 0.0);
            // 四舍五入保留一位小数
            BigDecimal rounded = BigDecimal.valueOf(avgStar).setScale(1, RoundingMode.HALF_UP);
            dto.setAvgStart(rounded.doubleValue());
            return dto;
        }).toList();
        return new PageResponseDTO<>(dtoList, coursePage.getTotal(), coursePage.getSize(), coursePage.getCurrent());
    }

    @Override
    public PageResponseDTO<CourseListDTO> getCourseRankingPage(int page, int size, String orderBy, String orderType) {
        QueryWrapper<Course> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("status", 1, 2);
        List<Course> allCourses = this.list(queryWrapper);

        List<CourseListDTO> fullList = allCourses.stream().map(course -> {
            CourseListDTO dto = new CourseListDTO();
            dto.setTitle(course.getTitle());

            User teacher = userMapper.selectById(course.getTeacherId());
            dto.setTeacherName(teacher != null ? teacher.getName() : "");

            dto.setLevel(course.getLevel());
            dto.setCoverUrl(course.getCoverUrl());
            dto.setCourseId(org.csu.onlineedubackend.util.HashIdUtil.generateHashId(course.getId()));
            dto.setPrice(course.getPrice());
            dto.setStatus(course.getStatus());
            dto.setCreatedAt(course.getCreatedAt());
            dto.setId(course.getId());

            int subscriberCount = courseSubscribeMapper.countByCourseId(course.getId());
            dto.setSubscriberCount(subscriberCount);

            Double avgStar = courseCommentMapper.selectAvgRatingByCourseId(course.getId());
            double star = avgStar != null ? avgStar : 0.0;
            BigDecimal rounded = BigDecimal.valueOf(star).setScale(1, RoundingMode.HALF_UP);
            dto.setAvgStart(rounded.doubleValue());

            return dto;
        }).collect(Collectors.toList());

        // 排序
        Comparator<CourseListDTO> comparator;
        if ("avgStart".equals(orderBy)) {
            comparator = Comparator.comparing(CourseListDTO::getAvgStart);
        } else {
            comparator = Comparator.comparing(CourseListDTO::getSubscriberCount);
        }
        if ("desc".equalsIgnoreCase(orderType)) {
            comparator = comparator.reversed();
        }
        fullList.sort(comparator);

        // 分页
        int fromIndex = Math.min((page - 1) * size, fullList.size());
        int toIndex = Math.min(fromIndex + size, fullList.size());
        List<CourseListDTO> pageList = fullList.subList(fromIndex, toIndex);

        return new PageResponseDTO<>(pageList, fullList.size(), size, page);
    }


    @Override
    public PageResponseDTO<CourseListDTO> getApprovalCoursePage(int page, int size, String status) {
        Page<Course> pageParam = new Page<>(page, size);
        QueryWrapper<Course> queryWrapper = new QueryWrapper<>();
        
        // 根据状态过滤
        if (status != null && !status.isEmpty()) {
            switch (status) {
                case "approved" -> queryWrapper.eq("status", 1); // 已上架
                case "offline" -> queryWrapper.eq("status", 2); // 已下架
                case "pending" -> queryWrapper.eq("status", 3); // 要核审的
                case "rejected" -> queryWrapper.eq("status", 4); // 已拒绝
                default -> {
                    // 默认显示所有需要审批相关的状态：1（上架）,2（下架）,3（要核审的），4（拒绝）
                    queryWrapper.in("status", 1, 2, 3, 4);
                }
            }
        } else {
            // 默认显示所有需要审批相关的状态：1（上架）,2（下架）,3（要核审的），4（拒绝）
            queryWrapper.in("status", 1, 2, 3, 4);
        }
        
        // 按创建时间倒序排列
        queryWrapper.orderByDesc("created_at");
        
        IPage<Course> coursePage = this.page(pageParam, queryWrapper);
        List<CourseListDTO> dtoList = coursePage.getRecords().stream().map(course -> {
            CourseListDTO dto = new CourseListDTO();
            dto.setTitle(course.getTitle());
            // 教师姓名
            User teacher = userMapper.selectById(course.getTeacherId());
            dto.setTeacherName(teacher != null ? teacher.getName() : "");
            dto.setLevel(course.getLevel());
            dto.setCoverUrl(course.getCoverUrl());
            dto.setCourseId(org.csu.onlineedubackend.util.HashIdUtil.generateHashId(course.getId()));
            dto.setPrice(course.getPrice());
            dto.setStatus(course.getStatus());
            dto.setCreatedAt(course.getCreatedAt());
            dto.setSubscriberCount(courseSubscribeMapper.countByCourseId(course.getId()));
            dto.setId(course.getId());
            return dto;
        }).toList();
        return new PageResponseDTO<>(dtoList, coursePage.getTotal(), coursePage.getSize(), coursePage.getCurrent());
    }

    @Override
    public boolean approveCourse(Integer courseId) {
        try {
            Course course = this.getById(courseId);
            if (course == null) {
                return false;
            }
            
            // 将课程状态设置为已发布（状态1）
            course.setStatus(1);
            course.setUpdatedAt(LocalDateTime.now());
            
            return this.updateById(course);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    @Override
    public boolean rejectCourse(Integer courseId) {
        try {
            Course course = this.getById(courseId);
            if (course == null) {
                return false;
            }
            
            // 将课程状态设置为拒绝（状态4）
            course.setStatus(4);
            course.setUpdatedAt(LocalDateTime.now());
            
            return this.updateById(course);

        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    public Long getCourseCommentCount(Integer courseId) {
        log.info("获取课程评论总数 - 课程ID: {}", courseId);
        try {
            QueryWrapper<CourseComment> wrapper = new QueryWrapper<>();
            wrapper.eq("course_id", courseId);
            return courseCommentMapper.selectCount(wrapper);
        } catch (Exception e) {
            log.error("获取课程评论总数失败 - 课程ID: {}, 错误: {}", courseId, e.getMessage(), e);
            return 0L;
        }
    }
    
    @Override
    public Double getCourseAverageRating(Integer courseId) {
        log.info("获取课程平均评分 - 课程ID: {}", courseId);
        try {
            Double avgRating = courseCommentMapper.selectAvgRatingByCourseId(courseId);
            return avgRating != null ? avgRating : 0.0;
        } catch (Exception e) {
            log.error("获取课程平均评分失败 - 课程ID: {}, 错误: {}", courseId, e.getMessage(), e);
            return 0.0;
        }
    }
}